home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / src / dc1 / error.c < prev    next >
C/C++ Source or Header  |  1997-09-09  |  6KB  |  264 lines

  1. /*
  2.  *    (c)Copyright 1992-1997 Obvious Implementations Corp.  Redistribution and
  3.  *    use is allowed under the terms of the DICE-LICENSE FILE,
  4.  *    DICE-LICENSE.TXT.
  5.  */
  6.  
  7. /*
  8.  *  ERROR.C
  9.  */
  10.  
  11. #include <fcntl.h>
  12. #ifdef linux
  13. #define NO_ULONG
  14. #endif
  15. #include "defs.h"
  16. #ifndef AMIGA
  17. #include <unistd.h>
  18. #endif
  19. #ifdef _DCC
  20. #include <exec/tasks.h>     /*    for SetRequester() */
  21. #include <dos/dos.h>
  22. #include <dos/dosextens.h>
  23. #include <clib/exec_protos.h>
  24. #endif
  25.  
  26. #ifndef O_BINARY
  27. #define O_BINARY    0
  28. #endif
  29.  
  30. Prototype void cerror(short, const char *, ...);
  31. Prototype void vcerror(long, short, const char *, va_list va, short);
  32. Prototype void zerror(short, ...);
  33. Prototype void yerror(long, short, ...);
  34. Prototype char *ObtainErrorString(short);
  35. Prototype void ExitError(short);
  36.  
  37. void *SetRequester(void *new);
  38.  
  39. char    *ErrorFileName1 = DCC_CONFIG "dice.errors";
  40. char    *ErrorFileName2 = DCC "config/dice.errors";
  41. char    *ErrorAry;
  42. short    ErrorArySize;
  43. char    ErrBuf[128];
  44.  
  45. void
  46. zerror(short errorId, ...)
  47. {
  48.     int etype = errorId & 0x0FFF;
  49.     char *ptr;
  50.     va_list va;
  51.  
  52.     ptr = ObtainErrorString(etype);
  53.  
  54.     va_start(va, errorId);
  55.     vcerror(((LFBase) ? LFBase->lf_Index : 0), errorId >> 12, ptr, va, etype);
  56.     va_end(va);
  57. }
  58.  
  59. void
  60. yerror(long lexIdx, short errorId, ...)
  61. {
  62.     int etype = errorId & 0x0FFF;
  63.     char *ptr;
  64.     va_list va;
  65.  
  66.     ptr = ObtainErrorString(etype);
  67.  
  68.     va_start(va, errorId);
  69.     vcerror(lexIdx, errorId >> 12, ptr, va, etype);
  70.     va_end(va);
  71. }
  72.  
  73.  
  74. #ifndef REGISTERED
  75. void
  76. cerror(short etype, const char *buf, ...)
  77. {
  78.     va_list va;
  79.  
  80.     va_start(va, buf);
  81.     vcerror(((LFBase) ? LFBase->lf_Index : 0), etype, buf, va, 0);
  82.     va_end(va);
  83. }
  84. #endif
  85.  
  86. void
  87. vcerror(long lexIdx, short etype, const char *buf, va_list va, short eno)
  88. {
  89.     static const char *TNames[] = { "?","Warning","Error", "Fatal", "SoftError"
  90. #ifndef REGISTERED
  91.     , "Unimplemented"
  92. #endif
  93.     };
  94.     long lexIdxBeg;
  95.     long lexFileNameLen;
  96.     long lexLine;
  97.     char *lexFile;
  98.     long errcol = 0;
  99.     char ebuf[100];
  100.     long ebufoff = 0;
  101.  
  102.     lexLine=FindLexFileLine(lexIdx, &lexFile, &lexFileNameLen, &lexIdxBeg);
  103.  
  104.     /*
  105.      * Use original lexer file to obtain line for printing since the
  106.      * internal copy could be munged.
  107.      *
  108.      * We need to determine a couple of things:
  109.      *  lexLine - Indicates the line number of the error (0 if no associated line)
  110.      *  errcol  - The physical column where the error occurred (0 for no line)
  111.      *  ebuf    - The null terminated buffer.  This buffer is at most 80 characters
  112.      *            but will contain the character position that has the error.
  113.      *  ebufoff - The logical start of the error buffer.  This will be 0 as long as
  114.      *            the error occurs in the first 80 columns.  Beyond that, this will
  115.      *            jump by 10.
  116.      * lexFile  - The name of the file containing the error
  117.      * lexFileNameLen
  118.      */
  119.  
  120.     ebuf[0] = 0;
  121.     if (lexLine && ErrorInFileValid) {
  122.  
  123.     short c;
  124.     long i = lexIdxBeg;
  125.     short pos = 0;
  126.  
  127.     while ((c = FindLexCharAt(i)) != EOF && c != '\n')
  128.     {
  129.         if (c == '\t')
  130.         {
  131.         short tab;
  132.         tab = ((pos + ebufoff + 8) & ~7) - ebufoff;
  133.         while (pos < tab)
  134.             ebuf[pos++] = ' ';
  135.         }
  136.         else
  137.         ebuf[pos++] = c;
  138.  
  139.         if (i == lexIdx)
  140.         errcol = pos + ebufoff;
  141.  
  142.         if (pos > 80)
  143.         {
  144.            if ((errcol - (pos + ebufoff)) > 10) break;
  145.            memcpy(ebuf, ebuf+10, pos-10);
  146.            pos -= 10;
  147.            ebufoff += 10;
  148.         }
  149.         ++i;
  150.     }
  151.     ebuf[pos] = 0;
  152.     }
  153.  
  154.     eprintf(1, "DC1: \"%.*s\" L:%d ", lexFileNameLen, lexFile, lexLine);
  155.  
  156.     if (ErrorOpt & 1)
  157.     eprintf(1, "C:%d %c:%d ", errcol + 1, TNames[etype][0], eno);
  158.     else
  159.     eprintf(1, "%s:%d ", TNames[etype], eno);
  160.  
  161.     veprintf(1, buf, va);
  162.     eprintf(1, "\n");
  163.  
  164.     if (lexLine && ErrorInFileValid && (ErrorOpt & 2))
  165.     {
  166.     short pos = errcol - ebufoff;
  167.  
  168.     /* We Need to account for the fact that the ^ will take up one space */
  169.     if (pos)
  170.        pos = pos - 1;
  171.  
  172.     eprintf(0, "%s\n%*.*s^\n", ebuf, pos, pos, "");
  173.     }
  174.  
  175.     if (etype == ESOFT || etype == EFATAL) {
  176.     ExitError(20);
  177.     }
  178.     if (etype == EWARN && ExitCode < 5)
  179.     ExitCode = 5;
  180.     if (etype != EWARN && ExitCode < 20)
  181.     ExitCode = 20;
  182. }
  183.  
  184. void
  185. ExitError(short code)
  186. {
  187.     DumpStats();
  188.     if (OutFileName) {
  189.     fclose(stdout);
  190.     remove(OutFileName);
  191.     }
  192.     if (ExitCode < code)
  193.     ExitCode = code;
  194.     exit(ExitCode);
  195. }
  196.  
  197. char *
  198. ObtainErrorString(short errNum)
  199. {
  200.     short i;
  201.     static char *UseFileName;
  202.  
  203.     if (ErrorAry == NULL) {
  204.     int fd;
  205.     short siz;
  206.     void *save;
  207.  
  208.     save = SetRequester((void *)-1);
  209.     UseFileName = ErrorFileName1;
  210.     fd = open(ErrorFileName1, O_RDONLY|O_BINARY);
  211.     SetRequester(save);
  212.     if (fd < 0) {
  213.         if ((fd = open(ErrorFileName2, O_RDONLY|O_BINARY)) < 0) {
  214.         sprintf(ErrBuf, "(can't open %s!)", ErrorFileName2);
  215.         return(ErrBuf);
  216.         }
  217.         UseFileName = ErrorFileName2;
  218.     }
  219.     siz = lseek(fd, 0L, 2);
  220.     lseek(fd, 0L, 0);
  221.     ErrorAry = malloc(siz + 1);
  222.     read(fd, ErrorAry, siz);
  223.     close(fd);
  224.     {
  225.         char *ptr;
  226.         for (ptr = strchr(ErrorAry, '\n'); ptr; ptr = strchr(ptr + 1, '\n'))
  227.         *ptr = 0;
  228.     }
  229.     ErrorAry[siz] = 0;
  230.     ErrorArySize = siz;
  231.     }
  232.     for (i = 0; i < ErrorArySize; i += strlen(ErrorAry + i) + 1) {
  233.     char *ptr;
  234.     if (ErrorAry[i] == 'C' && ErrorAry[i+1] == '1' && strtol(ErrorAry + i + 3, &ptr, 10) == errNum)
  235.         return(ptr + 1);
  236.     }
  237.     sprintf(ErrBuf, "(no entry in %s for error)", (UseFileName) ? UseFileName : "??");
  238.     return(ErrBuf);
  239. }
  240.  
  241. #ifdef AMIGA
  242.  
  243. void *
  244. SetRequester(void *new)
  245. {
  246.     void *old;
  247.     struct Process *proc = (struct Process *)FindTask(NULL);
  248.  
  249.     old = proc->pr_WindowPtr;
  250.     proc->pr_WindowPtr = new;
  251.     return(old);
  252. }
  253.  
  254. #else
  255.  
  256. void *
  257. SetRequester(void *new)
  258. {
  259.     return(NULL);
  260. }
  261.  
  262. #endif
  263.  
  264.